package com.listeningframework.boot.commons.string;

import org.apache.commons.collections.MapUtils;

import java.text.MessageFormat;
import java.util.Map;
import java.util.UUID;

/**
 * @author Listening
 * @version $Id: CommonStringUtils.java, v 0.1 2014年11月1日 下午6:53:21 Listening
 *          Exp $
 *          字符串工具类
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {

    private StringUtils() {

    }

    /**
     * Trim Blank Characters Or Wraps
     *
     * @param value 值
     * @return String
     */
    public static final String trimWrap(String value) {
        String tempValue = value == null ? "" : value.trim();
        return tempValue.replaceAll("\\s+", "");
    }

    /**
     * IS All Blank
     *
     * @param values 值
     * @return boolean
     */
    public static final boolean isAllBlank(String... values) {
        boolean result = true;
        for (String value : values) {
            if (isNotBlank(value)) {
                result = false;
                break;
            }
        }
        return result;
    }

    /**
     * 字符串字节长度
     *
     * @param value 值
     * @return Integer
     */
    public static Integer bytesLength(String value) {
        return RegExpUtils.length(value);
    }

    /**
     * 字符长度区间
     *
     * @param value 值
     * @param min   最小
     * @param max   最大
     * @return boolean
     */
    public static boolean length(String value, int min, int max) {
        int length = bytesLength(value);
        return length >= min && length <= max;
    }

    /**
     * 格式化字符串
     *
     * @param value  值
     * @param params 参数
     * @return String
     */
    public static String format(String value, Object... params) {
        return MessageFormat.format(value, params);
    }

    /**
     * 判断两个值是否相同
     *
     * @param valueOne 值1
     * @param valueTwo 值2
     * @return boolean
     */
    public static boolean isSame(String valueOne, String valueTwo) {
        // 都是空则相同(忽略空串和null,默认统一处理)
        if (isBlank(valueOne) && isBlank(valueTwo)) {
            return true;
        }
        // 都不为空,equal比较
        if (!isAnyBlank(valueOne, valueTwo)) {
            return valueOne.trim().equals(valueTwo.trim());
        }
        // 其一为空返回false
        return false;
    }

    /**
     * 处理String值非空去空格否则返回空串
     *
     * @param value 值
     * @return String
     */
    public static String getValue(String value) {
        return isBlank(value) ? "" : value.trim();
    }

    /**
     * 处理String值非空去空格否则返回默认值
     *
     * @param value 值
     * @param def   默认值
     * @return String
     */
    public static final String getValue(String value, String def) {
        return isBlank(value) ? def : value.trim();
    }

    /**
     * 从MAP取值
     *
     * @param paramMap  参数MAP
     * @param paramCode 参数编码
     * @return String
     */
    public static final String getValue(Map<String, Object> paramMap, String paramCode) {
        if (MapUtils.isEmpty(paramMap) || isEmpty(paramCode)) {
            return null;
        }
        Object value = paramMap.get(paramCode);
        return value == null ? null : String.valueOf(value).trim();
    }

    /**
     * Int转String
     *
     * @param value 参数值
     * @param def   默认值
     * @return String
     */
    public static final String getValue(Integer value, Integer def) {
        return (value == null) ? String.valueOf(def) : String.valueOf(value);
    }

    /**
     * Parse String To Integer
     *
     * @param value 待转换值
     * @return Integer
     */
    public static final Integer getIntValue(String value) {
        return getIntValue(value, null);
    }

    /**
     * Parse String To Integer
     *
     * @param value 待转换值
     * @param def   默认值
     * @return Integer
     */
    public static final Integer getIntValue(String value, Integer def) {
        if (isBlank(value)) {
            return def;
        }
        String trimVal = getValue(value);
        if (!RegExpUtils.isNumberic(trimVal)) {
            throw new RuntimeException("非数字内容不能进行转换");
        }
        return Integer.parseInt(value);
    }

    /**
     * Parse String To Long
     *
     * @param value 待转换值
     * @return Long
     */
    public static final Long getLongValue(String value) {
        return getLongValue(value, null);
    }

    /**
     * Parse String To Long
     *
     * @param value 待转换值
     * @param def   默认值
     * @return Long
     */
    public static final Long getLongValue(String value, Long def) {
        if (isBlank(value)) {
            return def;
        }
        String trimVal = getValue(value);
        if (!RegExpUtils.isNumberic(trimVal)) {
            throw new RuntimeException("非数字内容不能进行转换");
        }
        return Long.valueOf(trimVal);
    }

    /**
     * Get Integer Value From ParamMap
     *
     * @param paramMap  参数MAP
     * @param paramCode 参数编码
     * @param def       默认值
     * @return Integer
     */
    public static final Integer getIntValue(Map<String, Object> paramMap, String paramCode, Integer def) {
        String value = getValue(paramMap, paramCode);
        return getIntValue(value, def);
    }

    /**
     * Get Long Value From ParamMap
     *
     * @param paramMap  参数MAP
     * @param paramCode 参数编码
     * @param def       默认值
     * @return Long
     */
    public static Long getLongValue(Map<String, Object> paramMap, String paramCode, Long def) {
        String value = getValue(paramMap, paramCode);
        return getLongValue(value, def);
    }

    /**
     * Long 2 Integer
     *
     * @param value Long
     * @return Integer
     */
    public static Integer long2int(Long value) {
        return value == null ? 0 : Integer.parseInt(String.valueOf(value));
    }

    /**
     * Get File Suffix Name
     *
     * @param oriName 值
     * @return String
     */
    public static final String getFileSuffix(String oriName) {
        if (isBlank(oriName) || oriName.indexOf(".") == -1) {
            return null;
        }
        return oriName.substring(oriName.lastIndexOf("."));
    }

    /**
     * Is Not Emoji Character
     *
     * @param codePoint 值
     * @return boolean
     */
    public static boolean isNotEmojiCharacter(char codePoint) {
        if ((codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)) {
            return true;
        }
        if ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) {
            return true;
        }
        if ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) {
            return true;
        }
        return ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }

    /**
     * 过滤emoji 或者 其他非文字类型的字符
     *
     * @param source 值
     * @return String
     */
    public static String filterEmoji(String source) {
        if (isBlank(source)) {
            return "";
        }
        int len = source.length();
        StringBuilder buf = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (isNotEmojiCharacter(codePoint)) {
                buf.append(codePoint);
            }
        }
        return buf.toString().trim();
    }

    /**
     * Get UUID
     *
     * @return String
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().toUpperCase().replaceAll("[-]", "");
    }


    /**
     * 生成Get方法名称
     *
     * @param fieldName 字段名
     * @return String
     */
    public static final String generateGetMethodName(String fieldName) {
        return "get" + capitalize(fieldName);
    }

    /**
     * 生成Set方法名称
     *
     * @param fieldName 字段名
     * @return String
     */
    public static final String generateSetMethodName(String fieldName) {
        return "set" + capitalize(fieldName);
    }

    /**
     * 包名转路径
     *
     * @param packageName 字段名
     * @return String
     */
    public static final String package2Path(String packageName) {
        return packageName.replaceAll("\\.", "/");
    }

}
